import base64
import os

from django_redis import get_redis_connection
from rest_framework import serializers
# from rest_framework.settings import api_settings


from oauth.models import OAuthQQUser
from oauth.utils import OAuthQQ
from user.models import User


class OAuthQQUserSerializer(serializers.ModelSerializer):
    """保存QQ用户的登录数据"""
    sms_code = serializers.CharField(label="短信验证码", write_only=True)
    access_token = serializers.CharField(label="操作凭证", write_only=True)
    token = serializers.CharField(label="JWT token", read_only=True)
    mobile = serializers.RegexField(label="手机号", regex=r'^1[3-9]\d{9}$', write_only=True)
    class Meta:
        model = User
        fields = ("mobile", "password", "access_token", "token", "username", "id", "sms_code")
        extra_kwargs = {
            "username": {
                "read_only":True
            },
            "password": {
                "write_only": True,
                "min_length": 8,
                "max_length": 20,
                "error_messages":{
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }

    def validate(self, attrs):
        #检验access_token
        access_token = attrs["access_token"]

        openid = OAuthQQ.check_save_user_token(access_token)
        if not openid:
            raise serializers.ValidationError("无效的“access_token")
        attrs["openid"] = openid

        #检验短信验证码
        mobile = attrs["mobile"]
        sms_code = attrs["sms_code"]
        redis_conn = get_redis_connection("verify_codes")
        real_sms_code = redis_conn.get("sms_%s" % mobile)
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError("短信验证码错误")

        #如果用户存在，校验用户密码
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = None
        else:
            password = attrs["password"]
            if not user.check_password(password):
                raise serializers.ValidationError("密码错误")
        attrs["user"] = user
        print(attrs)

        return attrs
        #
        # # 如果mobile已注册，校验对应的密码是否正确
        # try:
        #     user = User.objects.get(mobile=mobile)
        # except User.DoesNotExist:
        #     # `mobile`未注册
        #     user = None
        # else:
        #     # `mobile`已注册
        #     password = attrs['password']
        #
        #     if not user.check_password(password):
        #         raise serializers.ValidationError('密码错误')
        #
        # attrs['user'] = user
        #
        # return attrs


    def create(self, validated_data):

        print(validated_data)
        openid = validated_data["openid"]
        user = validated_data["user"]
        mobile = validated_data["mobile"]
        password = validated_data["password"]

        if not user:
            # "如果用户不存在，创建用户，绑定openid(创建OAuthQQUser数据)"
            username = base64.b64encode(os.urandom(9))
            user = User.objects.create_user(username=username,mobile = mobile, password=password)

        OAuthQQUser.objects.create(user=user, openid=openid)

        # 签发jwt token
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        user.token = token

        return user

















# class QQAuthUserSerializer(serializers.ModelSerializer):
#     """QQ绑定数据序列化器类"""
#     sms_code = serializers.CharField(label='短信验证码', write_only=True)
#     access_token = serializers.CharField(label='加密OpenID', write_only=True)
#     token = serializers.CharField(label='JWT token', read_only=True)
#     mobile = serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$', write_only=True)
#
#     class Meta:
#         model = User
#         fields = ('id', 'username', 'mobile', 'password', 'sms_code', 'access_token', 'token')
#
#         extra_kwargs = {
#             'username': {
#                 'read_only': True
#             },
#             'password': {
#                 'write_only': True,
#                 'min_length': 8,
#                 'max_length': 20,
#                 'error_messages': {
#                     'min_length': '仅允许8-20个字符的密码',
#                     'max_length': '仅允许8-20个字符的密码',
#                 }
#             }
#         }
#
#     # 手机号格式，短信验证码是否正确，access_token是否有效
#     # def validate_mobile(self, value):
#     #     if not re.match(r'^1[3-9]\d{9}$', value):
#     #         raise serializers.ValidationError('手机号格式错误')
#     #
#     #     return value
#
#     def validate(self, attrs):
#         """
#         attrs: 数据校验时传入字典数据
#         """
#         # access_token是否有效
#         access_token = attrs['access_token']
#
#         openid = OAuthQQ.check_save_user_token(access_token)
#
#         if openid is None:
#             # access_token解密实现
#             raise serializers.ValidationError('无效的access_token')
#
#         attrs['openid'] = openid
#
#         # 短信验证码是否正确
#         mobile = attrs['mobile']
#
#         # 获取redis链接
#         redis_conn = get_redis_connection('verify_codes')
#         real_sms_code = redis_conn.get('sms_%s' % mobile)  # None bytes
#
#         if real_sms_code is None:
#             raise serializers.ValidationError('短信验证码已过期')
#
#         # 对比短信验证码
#         sms_code = attrs['sms_code']  # str
#
#         if real_sms_code.decode() != sms_code:
#             raise serializers.ValidationError('短信验证码错误')
#
#         # 如果mobile已注册，校验对应的密码是否正确
#         try:
#             user = User.objects.get(mobile=mobile)
#         except User.DoesNotExist:
#             # `mobile`未注册
#             user = None
#         else:
#             # `mobile`已注册
#             password = attrs['password']
#
#             if not user.check_password(password):
#                 raise serializers.ValidationError('密码错误')
#
#         attrs['user'] = user
#
#         return attrs
#
#     def create(self, validated_data):
#         """
#         validated_data: 字典，校验之后的数据
#         """
#         user = validated_data['user'] # None
#
#         if user is None:
#             # 如果`mobile`未注册，先创建一个新用户，然后再进行绑定
#             mobile = validated_data['mobile']
#             password = validated_data['password']
#             # 随机生成一个用户名
#             username = base64.b64encode(os.urandom(9)).decode()
#             user = User.objects.create_user(username=username, mobile=mobile, password=password)
#
#         # 保存绑定QQ登录数据
#         OAuthQQUser.objects.create(
#             openid=validated_data['openid'],
#             user=user
#         )
#
#         # 服务器生成一个jwt token字符串：保存用户的身份信息
#         from rest_framework_jwt.settings import api_settings
#
#         # 生成payload方法
#         jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
#         # 生成jwt token的方法
#         jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
#
#         # 生成payload
#         payload = jwt_payload_handler(user)
#         # 生成jwt token
#         token = jwt_encode_handler(payload)
#
#         # 给user对象增加token属性：保存jwt token数据
#         user.token = token
#
#         return user



